﻿@using Flagrum.Web.Persistence.Entities
@using Flagrum.Core.Utilities
@using Flagrum.Web.Features.AssetExplorer.Base
@using Flagrum.Web.Features.AssetExplorer.Data
@implements IDisposable

@inject IWpfService WpfService
@inject JSInterop Interop
@inject AppStateService AppState
@inject FlagrumDbContext Context
@inject IStringLocalizer<App> AppLocalizer

<div class="flex flex-row items-center p-2 sticky top-0 z-40 bg-grey-900">
    <span class="material-icons ml-2 mr-2 text-grey-200 text-sm">360</span>
    <span class="text-grey-200 text-sm">
        @{
            var rotateModifierKey = Context.GetString(StateKey.ViewportRotateModifierKey);
            var rotateMouseAction = Context.GetString(StateKey.ViewportRotateMouseAction).SpacePascalCase();
        }
        @($"{(rotateModifierKey is null or "None" ? "" : rotateModifierKey + " + ")}{rotateMouseAction}")
    </span>
    <span class="material-icons ml-10 mr-2 text-grey-200 text-sm">pan_tool</span>
    <span class="text-grey-200 flex-grow text-sm">
        @{
            var panModifierKey = Context.GetString(StateKey.ViewportPanModifierKey);
            var panMouseAction = Context.GetString(StateKey.ViewportPanMouseAction).SpacePascalCase();
        }
        @($"{(panModifierKey is null or "None" ? "" : panModifierKey + " + ")}{panMouseAction}")
    </span>
    <Button Icon="settings" Text=@AppLocalizer["Settings"] OnClick="OpenSettingsModal" CssClass="@(IsLoading ? "invisible" : "")"/>
</div>
<div id="viewportContainer" class="h-full bg-grey-700 row">
    @if (IsLoading)
    {
        <div class="flex flex-col items-center w-full">
            <div class="continuous-3"></div>
            <span class="block text-accent1-200 font-display font-bold mt-4 mr-2">Loading Model</span>
        </div>
    }
</div>

<CascadingValue Value="this">
    <ModelPreviewSettingsModal @ref="ModelPreviewSettingsModal"/>
</CascadingValue>

@code
{
    [CascadingParameter]
    public IAssetExplorerParent Parent { get; set; }

    [Parameter]
    public IAssetExplorerNode Item { get; set; }

    private IAssetExplorerNode _lastItem;
    private bool _isRendered;
    private bool IsLoading { get; set; }
    private ModelPreviewSettingsModal ModelPreviewSettingsModal { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            IsLoading = true;
            StateHasChanged();

            await Interop.ObserveElementResize(DotNetObjectReference.Create(this), "viewportContainer");

            try
            {
                var left = await Interop.GetElementLeftOffset("viewportContainer");
                var top = await Interop.GetElementTopOffset("viewportContainer");
                var width = await Interop.GetElementWidth("viewportContainer");
                var height = await Interop.GetElementHeight("viewportContainer");
                WpfService.Resize3DViewport((int)left, (int)top, (int)width, (int)height);
            }
            catch
            {
    // See https://github.com/Kizari/Flagrum/issues/33
    // This prevents an edge case, no catch logic is required to continue normal operation
            }

            WpfService.Set3DViewportVisibility(true);

    //var gpubinQuery = Item.Name.Replace(".gmdl.gfxbin", ".gpubin").Replace(".gmdl", "_0.gpubin");
    //var gpubin = Item.Parent.Children.Single(n => n.Path.EndsWith(gpubinQuery))!;
            await WpfService.ChangeModel(Item, Parent.CurrentView);

            _lastItem = Item;
            _isRendered = true;
            AppState.Is3DViewerOpen = true;

            IsLoading = false;
            StateHasChanged();
        }
    }

    protected override async Task OnParametersSetAsync()
    {
        if (_isRendered && Item.Path != _lastItem.Path)
        {
            IsLoading = true;
            StateHasChanged();

            WpfService.Set3DViewportVisibility(false);

            await Task.Run(async () => { await InvokeAsync(async () => await WpfService.ChangeModel(Item, Parent.CurrentView)); });

            WpfService.Set3DViewportVisibility(true);

            _lastItem = Item;
            IsLoading = false;
            StateHasChanged();
        }
    }

    [JSInvokable]
    public void OnResize(double left, double top, double width, double height)
    {
        WpfService.Resize3DViewport((int)left, (int)top, (int)width, (int)height);
    }

    public void Dispose()
    {
        WpfService.Set3DViewportVisibility(false);
        AppState.Is3DViewerOpen = false;
    }

    private void OpenSettingsModal()
    {
        ModelPreviewSettingsModal?.Open();
    }

    public void CallStateHasChanged()
    {
        StateHasChanged();
    }
}